package com.gismore.jsonp.core;

import com.gismore.jsonp.config.AppConfig;
import com.google.common.collect.Lists;
import com.google.common.io.LineProcessor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Log4j2
public class SourcePlaylistProcessor implements LineProcessor<List<SongVO>> {
	private static Pattern p = Pattern.compile(AppConfig.me().songFilePattern());

	private List<SongVO> retList = Lists.newArrayList();

	private Map<String, SongVO> targetSongMap;

	private List<String> noSupportSuffixList = AppConfig.me().noSupportSuffix();

	public SourcePlaylistProcessor(Map<String, SongVO> targetSongMap) {
		this.targetSongMap = targetSongMap;
	}

	@Override
	public boolean processLine(String line) throws IOException {
		line = line.trim();
		int commaIndex = StringUtils.indexOf(line, "#");
		if( commaIndex == 0 || commaIndex == 1){
			return true;
		}
		String filePath = line;
		if(filePath.startsWith("file://")){
			filePath = StringUtils.substringAfter(filePath, "file://");
		}
		File songFile = new File(filePath);
		if(!songFile.exists()){
			return true;
		}
		Matcher m = p.matcher(line);
		SongVO song = new SongVO();
		String artistName = null;
		String trackTitle = null;
		String albumTitle = null;
		if(m.find()){
			artistName = m.group("artistName").trim();
			trackTitle = m.group("trackTitle").trim();
		}
		String suffix = StringUtils.substringAfterLast(songFile.getName(),".");
		String fileName = StringUtils.substringAfterLast(line, "\\");
		song.setFileName(fileName);
		song.setFilePath(filePath);

		SongVO targetSong = targetSongMap.get(fileName);
		if(targetSong != null){
			log.debug("跳过分析已存在歌曲 {}.", fileName);
			song.setArtistName(targetSong.getArtistName());
			song.setTrackTitle(targetSong.getTrackTitle());
			song.setAlbumTitle(targetSong.getAlbumTitle());
		}else{
			try {
				if(noSupportSuffixList.contains(suffix.toLowerCase())){
					log.debug("跳过分析不支持歌曲 {}.", fileName);
					song.setArtistName(artistName == null ? "" : artistName);
					song.setTrackTitle(trackTitle == null? "": trackTitle);
					song.setAlbumTitle("");
				}else {
					log.info("开始分析歌曲 : {}",songFile.getName());
					boolean needCommit = false;
					AudioFile	f = AudioFileIO.read(songFile);
					Tag tag = f.getTagAndConvertOrCreateAndSetDefault();
					List<String> artists = tag.getAll(FieldKey.ARTIST);
					String artist = null;
					if(artists != null && !artists.isEmpty()){
						artist = String.join("&", artists);
					}
					if(StringUtils.isBlank(artist) && StringUtils.isNotBlank(artistName)){
						needCommit = true;
						artist = artistName;
						tag.addField(FieldKey.ARTIST, artist);
					}else if(artistName!=null && !artistName.equals(artist)){
						log.warn("artist不一致，文件名:{}，文件信息:{}",artistName,artist);
					}
					song.setArtistName(artist == null ? artistName : artist);
					String title = tag.getFirst(FieldKey.TITLE);
					if(StringUtils.isBlank(title) && StringUtils.isNotBlank(trackTitle)){
						needCommit = true;
						title = trackTitle;
						tag.addField(FieldKey.TITLE, title);
					}else if(trackTitle!=null && !trackTitle.equals(title)){
						log.warn("title不一致，文件名:{}，文件信息:{}", trackTitle, title);
					}
					song.setTrackTitle(title == null? trackTitle: title);
					String album = tag.getFirst(FieldKey.ALBUM);
					song.setAlbumTitle(album ==null? "":album);
					if(needCommit){
						f.commit();
					}
					log.info("歌曲 {} 分析完成.",songFile.getName());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		retList.add(song);
		return true;
	}

	@Override
	public List<SongVO> getResult() {
		return retList;
	}
}
